--参考 冰川镜华

local function IsHUDScreen(inst)    --界面有效
	if TheFrontEnd:GetActiveScreen() and TheFrontEnd:GetActiveScreen().name == "HUD" then
		return true
	end
	return false
end

local i26key = Class(function(self, inst)
	self.inst = inst
	self.enabled = true
	self.ticktime = 0
	self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )
	self.mousehandler = TheInput:AddMouseButtonHandler(function(button, down, x, y)
		self:OnMouseButton(button,down,x,y)
	end )

end)
--是否启用
function i26key:SetEnabled(enable)  
	self.enabled = enable
end
--是否可以释放技能
function i26key:MayCastSkill()  
	return self.enabled and IsHUDScreen(self.inst) 
	and not self.inst:HasTag("time_stopped")
	and not ThePlayer:HasTag("incar")	--这是什么 大概能猜到）
	and not (ThePlayer.components.health and ThePlayer.components.health:IsDead())
end
--计时
function i26key:SetTickTime(time)
	self.ticktime = time or self.ticktime or 0
end
--监听 推送 供下面的使用
	function i26key:OnRawKey(key, down) --监听按键 
		local player = ThePlayer
		if player ~= nil and key then
			if not down then
				player:PushEvent("i26kh_keyup", {inst = self.inst, key = key})
			elseif down  then
				player:PushEvent("i26kh_keydown", {inst = self.inst, key = key})
			end
		end
	end
	function i26key:OnMouseButton(button,down,x,y)  --监听鼠标
		local player = ThePlayer
		if player ~= nil and button then
			if  not down  then
				player:PushEvent("i26_mousebuttonup", {inst = self.inst, button = button})
			elseif  down  then
				player:PushEvent("i26_mousebuttondown", {inst = self.inst, button = button})
			end
		end
	end
--保持方法中的 做动作
function i26key:RpcAndMaster(Rpc,clientfn)
	local x,y,z = ( TheInput:GetWorldPosition() or Vector3(0,0,0) ):Get()
	local entity = TheInput:GetWorldEntityUnderMouse()
	local Namespace = Rpc.Namespace
	local Action = Rpc.Action
	if clientfn then
		clientfn(self.inst,x,y,z,entity)
	end
	if TheWorld.ismastersim then
		local masterfn = MOD_RPC_HANDLERS[Namespace][MOD_RPC[Namespace][Action].id]
		masterfn(self.inst,x,y,z,entity)
	else
		SendModRPCToServer( MOD_RPC[Namespace][Action], x,y,z,entity)
	end
end
--开始按下按键的计时方法	每隔self.ticktime秒 执行一次方法 和动作
function i26key:StartTrackingWhileDown(Rpc,keepfn)
	if not self.inst.i26keyHandlerTickTask then
		self.inst.i26keyHandlerTickTask = self.inst:DoTaskInTime(self.ticktime,function()
			self:RpcAndMaster(Rpc,keepfn)
			self:StopTrackingWhileDown()
			self:StartTrackingWhileDown(Rpc,keepfn)
		end )
	end
end
--停止保持计时	同时执行退出方法和动作
function i26key:StopTrackingWhileDown(Rpc,outfn)
	if self.inst.i26keyHandlerTickTask then
		self.inst.i26keyHandlerTickTask:Cancel()
	end
	self.inst.i26keyHandlerTickTask = nil
	if Rpc then
		self:RpcAndMaster(Rpc,outfn)
	end
end
--添加按键事件监听	*按键编号	*进入动作	*保持动作	*退出动作	*TickTime	*本地方法
function i26key:AddActionListenerWhileDown(name,EnterRpc,KeepRpc,OutRpc,TickTime,clientfns)
	local enterfn = clientfns and clientfns.enterfn or nil
	local keepfn = clientfns and clientfns.keepfn or nil
	local outfn = clientfns and clientfns.outfn or nil
	self.inst:ListenForEvent("i26kh_keydown", function(inst, data)
		if data.inst == ThePlayer and data.key == TUNING.i26key[name] then	--玩家和按键正确	局内自定义按键关键
			if self:MayCastSkill() then	--如果当前允许
				if EnterRpc then	--若有进入动作，执行
					self:RpcAndMaster(EnterRpc,enterfn)
				end
				if KeepRpc then	--如果有保持方法，那么开始计时
					self:SetTickTime(TickTime)
					self:StartTrackingWhileDown(KeepRpc,keepfn)
				end
			end
		end
	end)
	self.inst:ListenForEvent("i26kh_keyup", function(inst, data)
		if data.inst == ThePlayer and data.key == TUNING.i26key[name] then
			self:StopTrackingWhileDown(OutRpc,outfn)
		end
	end)
end
--添加单个动作的监听 和上面相比更加简单 只执行一次
function i26key:AddActionListener(Key,Rpc,isdown,clientfn)
	local keyevent = isdown and "i26kh_keydown" or "i26kh_keyup"
	local buttonevent = isdown and "i26_mousebuttondown" or "i26_mousebuttonup"

	self.inst:ListenForEvent(keyevent, function(inst, data)
		if data.inst == ThePlayer and data.key == TUNING.i26key[Key] then
			----按键的前提条件
			if self:MayCastSkill()  then
				self:RpcAndMaster(Rpc,clientfn)
			else
				-- local str = check(ThePlayer)
			end
		end
	end)
end
--添加鼠标操作的监听 
function i26key:AddMouseActionListener(button,Rpc,isdown,clientfn)
	local buttonevent = isdown and "i26_mousebuttondown" or "i26_mousebuttonup"

	self.inst:ListenForEvent(buttonevent, function(inst, data)
		if data.inst == ThePlayer and data.button == button then
			if self:MayCastSkill()  then
				self:RpcAndMaster(Rpc,clientfn)
			else
				-- local str = check(ThePlayer)
			end
		end
	end)
end
--鼠标落下保持抬起的监听 同按键
function i26key:AddMouseActionListenerWhileDown(button,EnterRpc,KeepRpc,OutRpc,TickTime,clientfns)
	local enterfn = clientfns and clientfns.enterfn or nil
	local keepfn = clientfns and clientfns.keepfn or nil
	local outfn = clientfns and clientfns.outfn or nil
	self.inst:ListenForEvent("i26_mousebuttondown", function(inst, data)
		if data.inst == ThePlayer and data.button == button then
			if self:MayCastSkill() then
				if EnterRpc then
					self:RpcAndMaster(EnterRpc,enterfn)
				end
				if KeepRpc then
					self:SetTickTime(TickTime)
					self:StartTrackingWhileDown(KeepRpc,keepfn)
				end
			end
		end
	end)

	self.inst:ListenForEvent("i26_mousebuttonup", function(inst, data)
		if data.inst == ThePlayer and data.button == button then
			self:StopTrackingWhileDown(OutRpc,outfn)
		end
	end)
end

return i26key